package cn.rtplay.esp32camcar;

import android.annotation.SuppressLint;
import android.bluetooth.le.ScanSettings;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Lifecycle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.uber.autodispose.AutoDispose;
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import cn.rtplay.esp32camcar.databinding.ActivityScanBinding;
import cn.rtplay.esp32camcar.toolUtils.LogUtil;
import cn.rtplay.esp32camcar.toolUtils.Tools;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;

public class ScanActivity extends AppCompatActivity {

    // Stops scanning after 20 seconds.
    private static final long SCAN_PERIOD = 20000;
    public static final String BROADCAST_SET_CAR_NO = "setCarNo";
    public static final String BROADCAST_SHOW_BUTTON = "showButton";
    public static final String BROADCAST_DATA_NUMBER = "number";
    public static final String BROADCAST_DATA_ADDRESS = "address";
    private final String TAG = "ScanActivity";

    private ActivityScanBinding mViewBinding;

    private final Context mContext = this;
    private LocalBroadcastManager localBroadcastManager;
    private boolean mIsScanning;
    private WifiManager wifiManager;

    private ScanRecyclerAdapter mScanRecyclerAdapter;
    private LinearLayoutManager mLayoutManager;
    private List<ScanItem> mLlist;

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        /* 接收wifi扫描列表广播 */
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { //扫描到WiFi列表
                List<ScanResult> results = wifiManager.getScanResults();
                if (results != null) {
                    LogUtil.d(TAG, "results size: " + results.size());
                    for (ScanResult res : results) {
                        LogUtil.d(TAG, "ssid:" + res.SSID);
                        showItem(res.SSID);
                    }
                }
            }
        }
    };

    @SuppressLint("UseCompatLoadingForDrawables")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        LogUtil.v(TAG, "onCreate: in");
        super.onCreate(savedInstanceState);
        mViewBinding = ActivityScanBinding.inflate(getLayoutInflater());
        setContentView(mViewBinding.getRoot());

        localBroadcastManager = LocalBroadcastManager.getInstance(this);

        // 获取WifiManager
        wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

        IntentFilter filter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        registerReceiver(mReceiver, filter);

        mLlist = new ArrayList<>();
        mScanRecyclerAdapter = new ScanRecyclerAdapter(mLlist);
        mLayoutManager = new LinearLayoutManager(this);
        mViewBinding.recyclerView.setLayoutManager(mLayoutManager);
        mViewBinding.recyclerView.setAdapter(mScanRecyclerAdapter);
        DividerItemDecoration decoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
        decoration.setDrawable(getResources().getDrawable(R.drawable.divider, null));
        mViewBinding.recyclerView.addItemDecoration(decoration);
        mScanRecyclerAdapter.setOnItemClickListener((view, position) -> {
            scanWIFI(false);
            Intent intent = new Intent(BROADCAST_SET_CAR_NO);
            intent.putExtra(BROADCAST_DATA_NUMBER, view.carNO.getText());
            intent.putExtra(BROADCAST_DATA_ADDRESS, view.carSSID.getText());
            localBroadcastManager.sendBroadcast(intent);
            finish();
        });
        mViewBinding.swipeLayout.setOnRefreshListener(() -> {
            //刷新动画开始后 回调此方法

            //设置不可见
            mViewBinding.swipeLayout.setRefreshing(false);
            mViewBinding.swipeLayout.clearAnimation();
            if (mIsScanning) {
                return;
            }
            scanWIFI(true);
            mScanRecyclerAdapter.clearAllItem();
        });
    }

    private void setRefreshing(boolean show) {
        if (show) {
            mIsScanning = true;
            mViewBinding.pbLoad.setVisibility(View.VISIBLE);
            mViewBinding.pbDown.setVisibility(View.GONE);
        } else {
            mIsScanning = false;
            mViewBinding.pbLoad.setVisibility(View.GONE);
            mViewBinding.pbDown.setVisibility(View.VISIBLE);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // Initializes list view adapter.
        scanWIFI(true);
    }

    @Override
    protected void onPause() {
        LogUtil.v(TAG, "onPause: in");
        super.onPause();
        overridePendingTransition(0, R.anim.pull_down_out);
    }

    @Override
    protected void onStop() {
        LogUtil.v(TAG, "onStop: in");
        Intent intent = new Intent(BROADCAST_SHOW_BUTTON);
        localBroadcastManager.sendBroadcast(intent);
        super.onStop();
    }

    @Override
    protected void onStart() {
        LogUtil.v(TAG, "onStart: in");
        super.onStart();
    }

    @Override
    protected void onRestart() {
        LogUtil.v(TAG, "onRestart: in");
        super.onRestart();
    }

    @Override
    protected void onDestroy() {
        LogUtil.v(TAG, "onRestart: in");
        super.onDestroy();
    }

    /*
     * 扫描列表
     */
    long DELAY_TIME = 2000;
    ScheduledExecutorService pool;

    private void scanWIFI(final boolean enable) {
        LogUtil.v(TAG, "scanWIFI in with:" + enable);
        if (enable) {
            if (pool == null) {
                pool = Executors.newScheduledThreadPool(1);
            }
            setRefreshing(true);
            pool.scheduleAtFixedRate(() -> wifiManager.startScan(), 0, DELAY_TIME, TimeUnit.MILLISECONDS);
            // Stops scanning after a pre-defined scan period.
            Observable.timer(SCAN_PERIOD, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY)))
                    .subscribe(aLong -> {
                        mIsScanning = false;
                        if (pool != null) {
                            LogUtil.v(TAG, "scanWIFI: stopScan");
                            setRefreshing(false);
                            pool.shutdown();
                            pool = null;
                        }
                    });
        } else {
            if (pool != null) {
                LogUtil.v(TAG, "scanWIFI: stopScan");
                setRefreshing(false);
                pool.shutdown();
                pool = null;
            }
        }
    }

    public ScanSettings createScanSetting() {
        ScanSettings.Builder builder = new ScanSettings.Builder();
        builder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
        //builder.setReportDelay(100);//设置延迟返回时间
        builder.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
        return builder.build();
    }

    /* ssid 格式
     * rtcar-redferg-142857
     * rtcar-[3字符颜色描述][3字符品牌描述][1字符型号描述]-[6字符车牌号描述]
     * 详细描述说明见conf格式说明。
     */
    void showItem(String ssid) {
        if (Tools.getKeyStringCount(ssid, "-") >= 2) {
            if (ssid.indexOf("rtcar") == 0) {
                if (!mScanRecyclerAdapter.findItemBySSID(ssid)) {
                    ScanItem item = new ScanItem(mContext, ssid.substring(6, 13), ssid.substring(14), ssid);
                    mScanRecyclerAdapter.addDataAppend(item);
                }
            }
        }
    }
}
